package com.plian.system.service.fr.gsalaryslip;

import com.plian.Tools.CollectionUtil;
import com.plian.Tools.StringUtil;
import com.plian.Tools.TokenUtil;
import com.plian.Tools.Tools;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.common.status.CustomCode;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.dao.fr.budgetadjustment.BudgetAdjustmentDao;
import com.plian.system.dao.fr.gsalaryslip.GsalarySlipAdjustmentDao;
import com.plian.system.dao.fr.gsalaryslip.GsalarySlipDao;
import com.plian.system.dao.fr.payrolladjustment.PayrollAdjustmentDao;
import com.plian.system.dao.pm.property.PropertyBasicsDao;
import com.plian.system.dao.sys.orgzation.OrgzationDao;
import com.plian.system.dao.sys.user.UserDao;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.page.Page;
import com.plian.system.service.sys.orgzation.OrgzationService;
import com.plian.system.service.wf.FormWorkflowService;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class GsalarySlipAdjustmentService {
    @Autowired
    private GsalarySlipDao gsalarySlipDao;
    @Autowired
    private GsalarySlipAdjustmentDao gsalarySlipAdjustmentDao;
    @Autowired
    private BudgetAdjustmentDao budgetAdjustmentDao;
    @Autowired
    private PayrollAdjustmentDao payrollAdjustmentDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private OrgzationDao orgzationDao;
    @Autowired
    private OrgzationService orgzationService;

    @Autowired
    private PropertyBasicsDao propertyBasicsDao;

    @Autowired
    private FormWorkflowService formWorkflowService;

    /**
     * logger属性.
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(GsalarySlipAdjustmentService.class);


    /* TODO DEL
     * 列表
     * */
    public ListResult<PageData> listPage(PageData pd) {
        try {
            if (Tools.isEmpty(pd.getString("orgId"))) {
                pd.put("orgId", TokenUtil.getTokenOrgId());
            }
            List<PageData> list = new ArrayList<>();
            List<PageData> orgList = orgzationService.getSubordinate().getList();
            if (CollectionUtil.isEmpty(orgList)) {
                return new ListResult<>(CustomCode.builder().message("企业树初始化失败").code(1999).success(false).build());
            }
            Page page = new Page(true, pd);
            if (pd.getString("summary") != null) {
                String year = pd.getString("year");
                if (StringUtil.isBlank(year)){
                    return new ListResult<>(CustomCode.builder().message("请选择年度").code(1999).success(false).build());
                }
                List<PageData> dataList = gsalarySlipAdjustmentDao.findListByYear(pd);
                Map<String, List<PageData>> dataMap = dataList.stream()
                        .collect(Collectors.groupingBy(data -> data.getString("orgId") + "_" + data.getString("tableTypeCode") + "_"));
                Map<String, PageData> summaryCodeDataMap = dataList.stream()
                        .collect(Collectors.toMap(data -> data.getString("orgId") + "_" + data.getString("tableTypeCode") + "_" + data.getString("summaryCode"), data -> data));

                list = getListTreeByYearDataMap(year, orgList, dataMap, summaryCodeDataMap);
            } else {
                list = getList(pd);
            }
            int pageTotal = (page.getPageNumber() - 1) * page.getPageSize();
            int pageTotal1 = page.getPageNumber() * page.getPageSize();
            ListResult<PageData> Result = new ListResult<>(CommonCode.SUCCESS);
            if (list.size() < pageTotal1) {
                Result.setList(list.subList(pageTotal, list.size()));
            } else {
                Result.setList(list.subList(pageTotal, pageTotal1));
            }
            Result.setTotal(list.size());
            return Result;
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ListResult<>(CommonCode.ERROR);
        }
    }

    public List<PageData> getList(PageData pd) throws Exception {
        PageData orgpd = orgzationDao.findbyid(pd.getString("orgId"));
        List<PageData> list = new ArrayList<>();
        List<PageData> parentList = new ArrayList<>();
        switch (orgpd.getString("typeCode")) {
            case "0":
                list = findlist(orgpd.getString("id"), "", "6");
                for (PageData p : list) {
                    p.put("hasChild", true);
                }
                break;
            case "1":
                list = findlist(orgpd.getString("id"), "", "0");
                break;
            case "2":
                list = findlist(orgpd.getString("id"), "", "0");
                break;
            case "3":
                orgzationService.getParentList(orgpd.getString("parentId"), parentList);
                int summaryCode = parentList.size();
                if (Tools.isEmpty(pd.getString("year"))) {
                    list = findlist(orgpd.getString("id"), "", "6", summaryCode - 1);
                } else {
                    list = findlist(orgpd.getString("id"), pd.getString("year"), "6", summaryCode - 1);
                }
                for (PageData p : list) {
                    p.put("hasChild", true);
                }
                break;
            default:
                break;

        }

        return list;
    }

    public ListResult<PageData> treeList(PageData pd) {
        try {
            if (Tools.isEmpty(pd.getString("orgId"))) {
                pd.put("orgId", TokenUtil.getTokenOrgId());
            }
            List<PageData> list = new ArrayList<>();
            List<PageData> orgList = orgzationService.getSubordinate().getList();
            if (CollectionUtil.isEmpty(orgList)) {
                return new ListResult<>(CustomCode.builder().message("企业树初始化失败").code(1999).success(false).build());
            }
            list = getListTree(orgList, pd);
            list = (List<PageData>) list.get(0).get("children");
            ListResult<PageData> Result = new ListResult<>(CommonCode.SUCCESS);
            Result.setList(list);
            Result.setTotal(list.size());
            return Result;
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ListResult<>(CommonCode.ERROR);
        }
    }

    public List<PageData> getListTreeByYearDataMap(String year, List<PageData> orgList, Map<String, List<PageData>> dataMap, Map<String, PageData> summaryCodeDataMap) throws Exception{
        List<PageData> tree = new ArrayList<>();
        for (PageData org : orgList) {
            List<PageData> orgChildren = (List<PageData>) org.get("children");
            List<PageData> parentList = new ArrayList<>();
            String typeCode = org.getString("typeCode");
            if (StringUtil.isBlank(typeCode)){
                continue;
            }
            String orgName = org.getString("name");
            String orgId = org.getString("id");
            String key0 = orgId+  "_0_";
            String key1 = orgId + "_1_";
            String key6 = orgId + "_6_";
            switch (typeCode) {
                case "0":

                    PageData pd06 = new PageData();
                    if (!dataMap.containsKey(key6)){
                        pd06.put("orgName", orgName);
                        pd06.put("tableTypeCode", "6");
                        pd06.put("year", year);
                        pd06.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                    }else {
                        pd06 = dataMap.get(key6).get(0);
                    }
                    tree.add(pd06);

                    List<PageData> childList0 = new ArrayList<>();
                    if (!dataMap.containsKey(key1)){
                        PageData pdd = new PageData();
                        pdd.put("orgName", orgName);
                        pdd.put("tableTypeCode", "1");
                        pdd.put("year", year);
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        childList0.add(pdd);
                    }else {
                        childList0.add(dataMap.get(key1).get(0));
                    }

                    if (!dataMap.containsKey(key0)){
                        PageData pdd = new PageData();
                        pdd.put("orgName", orgName);
                        pdd.put("tableTypeCode", "0");
                        pdd.put("year", year);
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        childList0.add(pdd);
                    }else {
                        childList0.add(dataMap.get(key0).get(0));
                    }

                    childList0.addAll(getListTreeByYearDataMap(year, orgChildren, dataMap, summaryCodeDataMap));
                    pd06.put("children", childList0);
                    break;
                case "1":
                    if (!dataMap.containsKey(key0)){
                        PageData pdd = new PageData();
                        pdd.put("orgName", orgName);
                        pdd.put("tableTypeCode", "0");
                        pdd.put("year", year);
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        tree.add(pdd);
                    }else {
                        tree.add(dataMap.get(key0).get(0));
                    }
                    break;
                case "2":
                    if (!dataMap.containsKey(key0)){
                        PageData pdd = new PageData();
                        pdd.put("orgName", orgName);
                        pdd.put("tableTypeCode", "0");
                        pdd.put("year", year);
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        tree.add(pdd);
                    }else {
                        tree.add(dataMap.get(key0).get(0));
                    }
                    break;
                case "3":
                    orgzationService.getParentList(org.getString("parentId"), parentList);
                    int summaryCode = parentList.size();
                    PageData pd = new PageData();
                    pd.put("id", org.getString("id"));
                    pd.put("typeCode", 2);
                    List<PageData> typeOrgs = orgzationDao.findorgbyidandtype(pd);
                    List<PageData> delOrgs = new ArrayList<>();
                    for (PageData orgType:typeOrgs){
                        for (PageData child : orgChildren){
                            if (child.getString("id").equals(orgType.getString("id"))){
                                delOrgs.add(child);
                            }
                        }
                    }
                    orgChildren.removeAll(delOrgs);
                    PageData pd36 = new PageData();
                    if (!summaryCodeDataMap.containsKey(key6 + (summaryCode - 1))){
                        pd36.put("orgName", orgName);
                        pd36.put("tableTypeCode", "6");
                        pd36.put("year", year);
                        pd36.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                    }else {
                        pd36 = summaryCodeDataMap.get(key6 + (summaryCode - 1));
                    }
                    tree.add(pd36);
                    List<PageData> childList3 = new ArrayList<>();
                    //遍历当前单位的下属子企业
                    PageData small6 = new PageData();
                    if (!summaryCodeDataMap.containsKey(key6 + summaryCode)){
                        small6.put("orgName", orgName);
                        small6.put("tableTypeCode", "6");
                        small6.put("year", year);
                        small6.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                    }else {
                        small6 = summaryCodeDataMap.get(key6 + summaryCode);
                    }
                    childList3.add(small6);
                    PageData pd31 = new PageData();
                    if (!summaryCodeDataMap.containsKey(key1 + summaryCode)){
                        pd31.put("orgName", orgName);
                        pd31.put("tableTypeCode", "1");
                        pd31.put("year", year);
                        pd31.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                    }else {
                        pd31 = summaryCodeDataMap.get(key1 + summaryCode);
                    }
                    childList3.add(pd31);
                    PageData pd30 = new PageData();
                    if (!summaryCodeDataMap.containsKey(key0 + summaryCode)){
                        pd30.put("orgName", orgName);
                        pd30.put("tableTypeCode", "0");
                        pd30.put("year", year);
                        pd30.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                    }else {
                        pd30 = summaryCodeDataMap.get(key0 + summaryCode);
                    }
                    childList3.add(pd30);

                    List<PageData> summarySmall = new ArrayList<>();
                    PageData small1 = new PageData();
                    if (!summaryCodeDataMap.containsKey(key1 + (summaryCode + 1))){
                        small1.put("orgName", orgName);
                        small1.put("tableTypeCode", "1");
                        small1.put("year", year);
                        small1.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                    }else {
                        small1 = summaryCodeDataMap.get(key1 +  (summaryCode + 1));
                    }
                    small1.put("isSmallSummary", 1);
                    summarySmall.add(small1);
                    PageData small0 = new PageData();
                    if (!summaryCodeDataMap.containsKey(key0 +  (summaryCode + 1))){
                        small0.put("orgName", orgName);
                        small0.put("tableTypeCode", "0");
                        small0.put("year", year);
                        small0.put("isSmallSummary", 1);
                        small0.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                    }else {
                        small0 = summaryCodeDataMap.get(key0 + (summaryCode + 1));
                    }
                    small0.put("isSmallSummary", 1);
                    summarySmall.add(small0);
                    summarySmall.addAll(getListTreeByYearDataMap(year, typeOrgs, dataMap, summaryCodeDataMap));
                    small6.put("children", summarySmall);
                    small6.put("isSmallSummary", 1);
                    childList3.addAll(getListTreeByYearDataMap(year, orgChildren, pd, summaryCodeDataMap));
                    pd36.put("children", childList3);
                    break;
                default:
                    break;
            }
        }
        return tree;
    }

    public List<PageData> getListTree(List<PageData> orgList, PageData pd) throws Exception {
        List<PageData> tree = new ArrayList<>();
        List<PageData> list = new ArrayList<>();
        for (PageData org : orgList) {
            List<PageData> orgChildren = (List<PageData>) org.get("children");
            List<PageData> parentList = new ArrayList<>();
//            if (CollectionUtil.isNotEmpty(orgChildren)) {
            switch (org.getString("typeCode")) {
                case "0":
                    if (Tools.isEmpty(pd.getString("year"))) {
                        list = findlist(org.getString("id"), "", "6");
                    } else {
                        list = findlist(org.getString("id"), pd.getString("year"), "6");
                    }
                    if (list.size() == 0) {
                        PageData pdd = new PageData();
                        pdd.put("orgName", org.getString("name"));
                        pdd.put("tableTypeCode", "6");
                        pdd.put("year", pd.getString("year"));
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        list.add(pdd);
                    }

                    for (PageData p : list) {
                        List<PageData> childList = new ArrayList<>();
                        //遍历当前单位的下属子企业
                        List<PageData> childs = new ArrayList<>();
                        childs = findlist(org.getString("id"), p.getString("year"), "0");
                        if (childs.size() > 0) {
                            for (PageData child : childs) {
                                childList.add(child);
                            }
                        } else {
                            PageData pdd = new PageData();
                            pdd.put("orgName", org.getString("name"));
                            pdd.put("tableTypeCode", "0");
                            pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                            childList.add(pdd);
                        }
                        childList.addAll(getListTree(orgChildren, pd));
                        p.put("children", childList);
                    }
                    tree.addAll(list);
                    break;
                case "1":
                    list = findlist(org.getString("id"), pd.getString("year"), "0");
                    if (list.size() == 0) {
                        PageData pdd = new PageData();
                        pdd.put("orgName", org.getString("name"));
                        pdd.put("tableTypeCode", "0");
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        list.add(pdd);
                    }
                    tree.addAll(list);
                    break;
                case "2":
                    list = findlist(org.getString("id"), pd.getString("year"), "0");
                    if (list.size() == 0) {
                        PageData pdd = new PageData();
                        pdd.put("orgName", org.getString("name"));
                        pdd.put("tableTypeCode", "0");
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        list.add(pdd);
                    }
                    tree.addAll(list);
                    break;
                case "3":
                    orgzationService.getParentList(org.getString("parentId"), parentList);
                    int summaryCode = parentList.size();
                    pd.put("id", org.getString("id"));
                    pd.put("typeCode", 2);
                    List<PageData> typeOrgs = orgzationDao.findorgbyidandtype(pd);
                    List<PageData> delOrgs = new ArrayList<>();
                    for (PageData orgType:typeOrgs){
                        for (PageData child:orgChildren){
                            if (child.getString("id").equals(orgType.getString("id"))){
                                delOrgs.add(child);
                            }
                        }
                    }
                    orgChildren.removeAll(delOrgs);
                    if (Tools.isEmpty(pd.getString("year"))) {
                        list = findlist(org.getString("id"), "", "6", summaryCode - 1);
                    } else {
                        list = findlist(org.getString("id"), pd.getString("year"), "6", summaryCode - 1);
                    }
                    if (list.size() == 0) {
                        PageData pdd = new PageData();
                        pdd.put("orgName", org.getString("name"));
                        pdd.put("tableTypeCode", "6");
                        pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                        list.add(pdd);
                    }
                    for (PageData p : list) {
                        List<PageData> childList = new ArrayList<>();
                        //遍历当前单位的下属子企业
                        List<PageData> childs = new ArrayList<>();
                        childs = findlist(org.getString("id"), p.getString("year"), "", summaryCode);
                        if (childs.size() > 0) {
                            for (PageData child : childs) {
                                if ("6".equals(child.getString("tableTypeCode"))) {
                                    List<PageData> summarySmall = findlist(org.getString("id"), p.getString("year"), "0", summaryCode + 1);
                                    for (PageData branch : typeOrgs) {
                                        List<PageData> branchOrgs = findlist(branch.getString("id"), p.getString("year"), "0", summaryCode + 1);
                                        if (branchOrgs.size()>0){
                                            summarySmall.addAll(branchOrgs);
                                        }else {
                                            PageData pdd = new PageData();
                                            pdd.put("orgName", branch.getString("name"));
                                            pdd.put("tableTypeCode", "0");
                                            pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                                            summarySmall.add(pdd);
                                        }

                                    }
                                    for (PageData branchpd : summarySmall) {
                                        if ("1".equals(branchpd.getString("tableTypeCode"))) {
                                            branchpd.put("isSmallSummary", 1);
                                        }
                                    }
                                    child.put("children", summarySmall);
                                    child.put("isSmallSummary", 1);
                                }
                                childList.add(child);
                            }
                        } else {
                            PageData pdd = new PageData();
                            pdd.put("orgName", org.getString("name"));
                            pdd.put("tableTypeCode", "6");
                            pdd.put("status", String.valueOf(FormStatusConstant.NOFILLING));
                            childList.add(pdd);
                        }
                        childList.addAll(getListTree(orgChildren, pd));
                        p.put("children", childList);
                    }
                    tree.addAll(list);
                    break;
                default:
                    break;
            }
        }
//        }
        return tree;
    }

    public List<PageData> findlist(String id, String year, String type) throws Exception {
        return findlist(id, year, type, 999);
    }

    /*
     * 列表界面查询
     *
     * */
    public List<PageData> findlist(String id, String year, String type, int summaryCode) throws Exception {
        PageData pd = new PageData();
        pd.put("unit", id);
        if (!Tools.isEmpty(year)) {
        pd.put("year", year);
        }
        if ("0".equals(type)) {
            type = "budget.fhTableTypeCode != '6'";
            pd.put("formType", type);
        } else if ("6".equals(type)) {
            type = "budget.fhTableTypeCode = '6'";
            pd.put("formType", type);
        }
        if (summaryCode != 999) {
            String summary = String.valueOf(summaryCode);
            pd.put("summaryCode", summary);
        }
        List<PageData> valueList = gsalarySlipAdjustmentDao.listByCondition(pd);
        return valueList;

    }

    /**
     * 封装list方法
     *
     * @return
     */
    public List<PageData> alist(PageData pd) throws Exception {
        List<PageData> valuelist = new ArrayList<>();
        PageData pd_column = new PageData();
        pd_column.put("orgId", pd.getString("orgId"));
        List<PageData> colist = new ArrayList<>();
        if ("budget".equals(pd.getString("type"))){
            pd.put("id",pd.getString("budgetId"));
            colist = budgetAdjustmentDao.findcolumn(pd_column);
        }else {
            pd.put("id",pd.getString("payrollId"));
            colist = payrollAdjustmentDao.findcolumn(pd_column);
        }
        String value = "";
        for (int i = 0; i < colist.size(); i++) {
            PageData p = colist.get(i);
            String v = p.getString("columnId");
            if ("".equals(value)) {
                value += " max(CASE c.columnId WHEN '" + v + "' THEN v.`values` ELSE '' END) AS " + "c" + i;
            } else {
                value += " ,max(CASE c.columnId WHEN '" + v + "' THEN v.`values` ELSE '' END) AS " + "c" + i;
            }
        }
        pd.put("vaues", value);
        if ("budget".equals(pd.getString("type"))){
            valuelist = budgetAdjustmentDao.findvalue(pd);
        }else {
            valuelist = payrollAdjustmentDao.findvalue(pd);
        }

        return valuelist;
    }

    /**
     * 查询值表
     */
    public ListResult<PageData> valuelist(PageData pd) {
        try {
            String extra = "";
            List<PageData> budgetAdjustmentList = budgetAdjustmentDao.listAllOrg(new PageData());
            List<PageData> payrollAdjustmentList = payrollAdjustmentDao.listAllOrg(new PageData());
            for (PageData budget : budgetAdjustmentList){
                if (pd.getString("orgId").equals(budget.getString("orgId"))){
                    pd.put("type","budget");
                }
            }
            for (PageData payroll:payrollAdjustmentList){
                if (pd.getString("orgId").equals(payroll.getString("orgId"))){
                    pd.put("type","payroll");
                }
            }

            String msg = "";
            List<PageData> valuelist = new ArrayList<>();
            valuelist = alist(pd);
            ListResult<PageData> Result = new ListResult<>(CommonCode.SUCCESS);
            Result.setList(valuelist);
            Result.setRemark(extra);
            return Result;
        } catch (Exception e) {
             LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ListResult<>(CommonCode.ERROR);
        }
    }

    /**
     * 全面预算  工资预算表数据
     */
    public ListResult<PageData> gsalarySlipValueList(PageData pd) throws Exception{
        pd.put("fillingType", 1);
        PageData payroll = payrollAdjustmentDao.findzb(pd);
        if (payroll == null) {
            return new ListResult<>(CommonCode.SUCCESS);
        }

        PageData queryPd = new PageData();
        queryPd.put("payrollId", payroll.getString("id"));
        queryPd.put("orgId", pd.getString("orgId"));
        ListResult<PageData> results = new ListResult<>(CommonCode.SUCCESS);
        results.setList(alist(queryPd));
        return results;
    }

}

